# -*- coding: utf-8 -*-
# sudo apt-get install libglu1-mesa-dev freeglut3-dev
import sys
import random
from cmath import cos, sin
from PyQt5 import QtCore, QtWidgets
from OpenGL.GL import *
from OpenGL.GLU import gluPerspective

import cgitb

from PyQt5.QtCore import pyqtSignal

cgitb.enable(format='text')  # 解决pyqt5异常只要进入事件循环,程序就崩溃,而没有任何提示


class GLWidget(QtWidgets.QOpenGLWidget):
    def __init__(self):
        super().__init__()  # 调用父类构造函数
        # 初始化旋转角度
        self.x_rotation = 0  # 绕 X 轴的旋转角度
        self.y_rotation = 0  # 绕 Y 轴的旋转角度
        self.z_rotation = 0  # 绕 Z 轴的旋转角度

    def initializeGL(self):
        # OpenGL 初始化设置
        glEnable(GL_DEPTH_TEST)  # 启用深度测试，以确保正确的遮挡效果

    def resizeGL(self, width, height):
        # 调整视口和投影矩阵以适应窗口大小
        glViewport(0, 0, width, height)  # 设置视口
        glMatrixMode(GL_PROJECTION)  # 选择投影矩阵
        glLoadIdentity()  # 重置投影矩阵
        # 设置透视投影参数：视野角度、宽高比、近裁剪面和远裁剪面
        gluPerspective(45, (width / height) if height != 0 else 1, 0.1, 100.0)
        glMatrixMode(GL_MODELVIEW)  # 切换回模型视图矩阵

    def paintGL(self):
        # 清空颜色和深度缓冲
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glLoadIdentity()  # 重置模型视图矩阵
        # 设置相机位置：沿 Z 轴向后移动 5 个单位
        glTranslatef(0.0, 0.0, -5.0)
        # 旋转立方体
        glRotatef(self.x_rotation, 1, 0, 0)  # 绕 X 轴旋转
        glRotatef(self.y_rotation, 0, 1, 0)  # 绕 Y 轴旋转
        glRotatef(self.z_rotation, 0, 0, 1)  # 绕 Z 轴旋转
        self.drawCube()  # 调用绘制立方体的函数

    def drawCube(self):
        # 绘制一个立方体
        glBegin(GL_QUADS)  # 开始绘制四边形

        # 前面 (红色)
        glColor3f(1, 0, 0)  # 设置颜色为红色
        glVertex3f(-1, -1, 1)  # 左下角
        glVertex3f(1, -1, 1)  # 右下角
        glVertex3f(1, 1, 1)  # 右上角
        glVertex3f(-1, 1, 1)  # 左上角

        # 后面 (绿色)
        glColor3f(0, 1, 0)  # 设置颜色为绿色
        glVertex3f(-1, -1, -1)  # 左下角
        glVertex3f(-1, 1, -1)  # 左上角
        glVertex3f(1, 1, -1)  # 右上角
        glVertex3f(1, -1, -1)  # 右下角

        # 顶面 (蓝色)
        glColor3f(0, 0, 1)  # 设置颜色为蓝色
        glVertex3f(-1, 1, -1)  # 左后
        glVertex3f(-1, 1, 1)  # 左前
        glVertex3f(1, 1, 1)  # 右前
        glVertex3f(1, 1, -1)  # 右后

        # 底面 (黄色)
        glColor3f(1, 1, 0)  # 设置颜色为黄色
        glVertex3f(-1, -1, -1)  # 左后
        glVertex3f(1, -1, -1)  # 右后
        glVertex3f(1, -1, 1)  # 右前
        glVertex3f(-1, -1, 1)  # 左前

        # 右面 (品红色)
        glColor3f(1, 0, 1)  # 设置颜色为品红色
        glVertex3f(1, -1, -1)  # 右后
        glVertex3f(1, 1, -1)  # 右前
        glVertex3f(1, 1, 1)  # 右上
        glVertex3f(1, -1, 1)  # 右下

        # 左面 (青色)
        glColor3f(0, 1, 1)  # 设置颜色为青色
        glVertex3f(-1, -1, -1)  # 左后
        glVertex3f(-1, -1, 1)  # 左前
        glVertex3f(-1, 1, 1)  # 左上
        glVertex3f(-1, 1, -1)  # 左后

        glEnd()  # 结束绘制

    def setXRotation(self, x_angle):
        # 设置旋转角度并更新视图
        self.x_rotation = x_angle  # 更新 X 轴旋转角度
        self.update()  # 请求重新绘制

    def setYRotation(self, y_angle):
        # 设置旋转角度并更新视图
        self.y_rotation = y_angle  # 更新 Y 轴旋转角度
        self.update()  # 请求重新绘制

    def setZRotation(self, z_angle):
        # 设置旋转角度并更新视图
        self.z_rotation = z_angle  # 更新 Z 轴旋转角度
        self.update()  # 请求重新绘制

    def resetRotation(self):
        self.x_rotation = 0
        self.y_rotation = 0
        self.z_rotation = 0
        self.update()


class GyroWidget(QtWidgets.QWidget):
    gyroResultSignal = pyqtSignal(int)

    def __init__(self, parent=None):
        super(GyroWidget, self).__init__(parent)
        self.maxDegree = None
        self.minDegree = None

        self.glWidget = GLWidget()

        # 创建拨盘和标签
        self.xDial, self.xLabel = self.createDialLabel("X:", self.glWidget.setXRotation)
        self.yDial, self.yLabel = self.createDialLabel("Y:", self.glWidget.setYRotation)
        self.zDial, self.zLabel = self.createDialLabel("Z:", self.glWidget.setZRotation)

        resetButton = QtWidgets.QPushButton("Reset Rotation")
        resetButton.clicked.connect(self.ResetRotation)  # 连接按钮事件

        # 主布局
        mainLayout = QtWidgets.QVBoxLayout()
        mainLayout.addWidget(self.glWidget)

        # 创建并排布局
        dialLayout = QtWidgets.QHBoxLayout()
        dialLayout.addLayout(self.createDialLayout(self.xDial, self.xLabel))
        dialLayout.addLayout(self.createDialLayout(self.yDial, self.yLabel))
        dialLayout.addLayout(self.createDialLayout(self.zDial, self.zLabel))
        mainLayout.addLayout(dialLayout)

        mainLayout.addWidget(resetButton)  # 添加按钮到布局
        self.setLayout(mainLayout)

        self.xDial.setValue(0)
        self.yDial.setValue(0)
        self.zDial.setValue(0)

        # self.timer = QtCore.QTimer(self)
        # self.timer.timeout.connect(self.randomFlip)
        # self.timer.start(1000)

        self.setWindowTitle("3D Rotation Example")

    def createDialLabel(self, label_text, slot):
        dial = QtWidgets.QDial()
        dial.setRange(-18000, 18000)  # 0 to 360 degrees in 10 units
        dial.valueChanged.connect(lambda value: slot(value / 100.00))

        label = QtWidgets.QLabel(label_text + " 0.00")
        dial.valueChanged.connect(lambda value: label.setText(f"{label_text} {value / 100.0:.2f}"))  # 保留2位小数
        # 设置拨盘的大小
        dial.setFixedSize(88, 88)  # 调整大小
        # 设置标签的字体大小
        label.setStyleSheet("font-size: 33px; font-weight: bold;")
        label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)  # 设置标签居中对齐
        return dial, label

    def createDialLayout(self, dial, label):
        layout = QtWidgets.QHBoxLayout()
        layout.addWidget(label)
        layout.addWidget(dial)
        return layout

    def ResetRotation(self):
        self.UpdateUI(0, 0, 0)
        self.glWidget.resetRotation()

    def randomFlip(self):
        random_x = random.uniform(-180, 180)  # 随机角度
        random_y = random.uniform(-180, 180)
        random_z = random.uniform(-180, 180)
        self.UpdateUI(random_x, random_y, random_z)

    def gyroDataHandle(self, gyro):
        # print(gyro)
        words = gyro.split(",")
        myDegreeX = int(words[0]) / 2 - 100
        myDegreeY = int(words[1]) / 2 - 100
        myDegreeZ = int(words[2]) / 2 - 100
        print(f"{myDegreeX},{myDegreeY},{myDegreeZ}")
        # myDegree = (gyro / 2 - 100)
        # print(gyro)
        # if self.maxDegree is None or myDegree > self.maxDegree:
        #    self.maxDegree = myDegree
        # if self.minDegree is None or myDegree < self.minDegree:
        #    self.minDegree = myDegree
        self.UpdateUI(myDegreeX, myDegreeY, myDegreeZ)
        # if self.maxDegree - self.minDegree > 100:
        #    if not self.pixmapPass.isVisible():
        #        self.pixmapPass.setVisible(True)
        #        self.gyroResultSignal.emit(0)

    def UpdateUI(self, x_angle, y_angle, z_angle):
        # self.xLabel.setText(f"X: {x_angle:.2f}")
        # self.yLabel.setText(f"Y: {y_angle:.2f}")
        # self.zLabel.setText(f"Z: {z_angle:.2f}")
        self.xDial.setValue(int(x_angle * 100))
        self.yDial.setValue(int(y_angle * 100))
        self.zDial.setValue(int(z_angle * 100))
        self.glWidget.setXRotation(x_angle)
        self.glWidget.setYRotation(y_angle)
        self.glWidget.setZRotation(z_angle)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = GyroWidget()
    window.resize(800, 600)
    window.show()
    sys.exit(app.exec_())
